package com.ppc.service.impl;


import com.ppc.constant.EmployerConstant;
import com.ppc.constant.MessageConstant;
import com.ppc.constant.PictureConstant;
import com.ppc.context.BaseContext;
import com.ppc.dto.EmployerChangeInfoDTO;
import com.ppc.dto.EmployerLoginDTO;
import com.ppc.dto.UserLoginVerifyCodeDTO;
import com.ppc.entity.File;
import com.ppc.entity.Recording;
import com.ppc.entity.Requirement;
import com.ppc.entity.Task;
import com.ppc.entity.UserPPC;
import com.ppc.entity.Worker;
import com.ppc.exception.AccountLockedException;
import com.ppc.exception.AccountNotFoundException;
import com.ppc.exception.BaseException;
import com.ppc.exception.DeletionNotAllowedException;
import com.ppc.exception.FileException;
import com.ppc.exception.PasswordErrorException;
import com.ppc.mapper.employer.EmployerMapper;
import com.ppc.mapper.user.FileMapper;
import com.ppc.mapper.user.UserMapper;
import com.ppc.service.EmployerService;
import com.ppc.utils.MinIoUtil;
import com.ppc.vo.EmployerDataVO;
import com.ppc.vo.EmployerLoginVO;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 雇主账号实现
 *
 * @author LENOVO
 * @date 2023/12/20
 */
@Service
public class EmployerServiceImpl implements EmployerService {

  @Autowired
  private FileMapper fileMapper;

  @Autowired
  private EmployerMapper employerMapper;

  @Autowired
  private MinIoUtil minIoUtil;

  @Autowired
  private UserMapper userMapper;

  /**
   * 雇主登录
   *
   * @param employerLoginDTO
   * @return {@link EmployerLoginVO}
   */
  @Override
  public EmployerLoginVO login(EmployerLoginDTO employerLoginDTO) {
    String userPassword = employerLoginDTO.getEmployerPassword();
    userPassword = DigestUtils.md5DigestAsHex(userPassword.getBytes());
    UserPPC user = UserPPC.builder()
        .userEmail(employerLoginDTO.getEmployerEmail())
        .userPhone(employerLoginDTO.getEmployerPhone())
        .userPassword(employerLoginDTO.getEmployerPassword())
        .build();
    System.out.println(user);
    EmployerLoginVO employer = employerMapper.getEmployerByUsernameAndPwd(user);
    String realPassword = employerMapper.getPasswordByPhoneOrEmail(user);
    if (employer == null) {
      //账号不存在
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
    } else if (!userPassword.equals(realPassword)) {
      //密码错误
      throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
    } else if (employer.getEmployerStatus() == EmployerConstant.DISABLE) {
      //账号被锁定
      throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
    } else if (employer.getEmployerStatus() == EmployerConstant.UNREGISTER) {
      //账号已注销
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_UNREGISTER);
    }
    //利用minio获取文件路径
    employer.setFileUrl(minIoUtil.getFileUrl(employer.getFileUrl()));

    return employer;
  }

  @Override
  public EmployerLoginVO loginVerfiy(UserLoginVerifyCodeDTO userLoginVerifyCodeDTO) {

   UserPPC user = UserPPC.builder()
        .userEmail(userLoginVerifyCodeDTO.getUserEmail())
        .userPhone(userLoginVerifyCodeDTO.getUserPhone())
        .build();
    System.out.println(user);
    EmployerLoginVO employer = employerMapper.getEmployerByUsernameAndPwd(user);
    if (employer == null) {
      //账号不存在
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
    } else if (employer.getEmployerStatus() == EmployerConstant.DISABLE) {
      //账号被锁定
      throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
    } else if (employer.getEmployerStatus() == EmployerConstant.UNREGISTER) {
      //账号已注销
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_UNREGISTER);
    }
    //利用minio获取文件路径
    employer.setFileUrl(minIoUtil.getFileUrl(employer.getFileUrl()));

    return employer;
  }

  /**
   * @param file
   * @return {@link String }
   * @description
   */
  @Transactional
  @Override
  public Long uploadImg(MultipartFile file) {
    String originalFilename = file.getOriginalFilename();
    int lastIndexOf = originalFilename.lastIndexOf(".");
    String extension = originalFilename.substring(lastIndexOf + 1);

    if (!PictureConstant.SUPPORT_PICTURE.contains(extension)) {
      throw new FileException(MessageConstant.UNSUPPORT_FILE_TYPE + extension);
    } else {

      String objectName = minIoUtil.updateFileName(originalFilename);
      String filepath = minIoUtil.getFileUrl(objectName);

      try {
        minIoUtil.upload(objectName, file);
        //在file表添加一条
        File imgFile = File.builder()
            .fileName(originalFilename)
            .fileUrl(objectName)
            .fileType(extension)
            .build();

        fileMapper.insertFile(imgFile);
        employerMapper.updateImg(imgFile.getFileId(), BaseContext.getCurrentId());
        return imgFile.getFileId();
      } catch (Exception e) {
        throw new FileException(MessageConstant.UPLOAD_FAILED);
      }
    }


  }

  /**
   * @param fileId
   * @return {@link String }
   * @description
   *///@TODO 这里还需要联合查询，查询这个fileid是否是雇主发布需求的文件
  @Override
  public String downFile(Long fileId) {
    File file = fileMapper.selectFileById(fileId);
    String fileUrl = minIoUtil.getFileUrl(file.getFileUrl());
    return fileUrl;

  }

  /**
   * 雇主查看“我的资料”
   *
   * @return
   */
  @Override
  public EmployerDataVO checkData() {
    Long userId = BaseContext.getCurrentId();
    Long employerId = employerMapper.getEmployerIdByUserId(userId);
    EmployerDataVO employerDataVO = employerMapper.getData(employerId);
    return employerDataVO;
  }

  /**
   * 雇主修改“我的资料”
   *
   * @param employerChangeInfoDTO
   */
  @Override
  public void changeInformation(EmployerChangeInfoDTO employerChangeInfoDTO) {
    Long userId = BaseContext.getCurrentId();
    String userPassword = employerChangeInfoDTO.getUserPassword();
    if(userPassword!=null&&userPassword!="") {
      userPassword = DigestUtils.md5DigestAsHex(userPassword.getBytes());
    }
    UserPPC userPPC=UserPPC.builder()
        .userId(userId)
        .userName(employerChangeInfoDTO.getUserName())
        .userEmail(employerChangeInfoDTO.getUserEmail())
        .userPhone(employerChangeInfoDTO.getUserPhone())
        .userPassword(userPassword)
        .fileId(employerChangeInfoDTO.getFileId())
        .gender(employerChangeInfoDTO.getGender())
        .birthday(employerChangeInfoDTO.getBirthday())
        .build();
    if((userPPC.getUserPhone()!=null&&userPPC.getUserPhone()!="")||
        (userPPC.getUserEmail()!=null&&userPPC.getUserEmail()!="")) {
      List<UserPPC> userPPCList = userMapper.getUserByPhoneOrEmail(userPPC.getUserPhone(),userPPC.getUserEmail());
      if(userPPCList.size()>0) {
        throw new BaseException("该邮箱或手机号已被注册");
      }
    }
    employerMapper.changeInformationInPPC(userPPC);
  }



  /**
   * 雇主充值钱包
   * @param amount
   */
  @Override
  public void employerRecharge(Float amount) {
    if(amount==null) {
      throw new BaseException("输入金额不能为空");
    }
    Long userId= BaseContext.getCurrentId();
    Long employerId=employerMapper.getEmployerIdByUserId(userId);
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String localDateTime = formatter.format(LocalDateTime.now());
    Float count=employerMapper.getCount(employerId);
    Float employerCount=amount+count;
    employerMapper.recharge(employerCount,employerId);
    if(amount<0) {
      throw new DeletionNotAllowedException("输入错误,请输入大于0的金额");
    }
    Recording recording = Recording.builder()
            .recordingContent(localDateTime + " 成功充值" +
                    amount + "元,钱包余额"+ employerCount+ "元")
            .recordingType(0)
            .userId(userId)
            .build();
    employerMapper.createCreditRecording(recording);
  }

  /**
   * 雇主查看当前信誉
   *
   * @return
   */
  @Override
  public int checkCredit() {
    Long userId = BaseContext.getCurrentId();
    Long employerId = employerMapper.getEmployerIdByUserId(userId);
    int employerCredit = employerMapper.getCredit(employerId);
    return employerCredit;
  }

  /**
   * 雇主查看钱包余额
   *
   * @return
   */
  @Override
  public Float checkWallet() {
    Long userId = BaseContext.getCurrentId();
    Long employerId = employerMapper.getEmployerIdByUserId(userId);
    Float employerCount = employerMapper.getCount(employerId);
    return employerCount;
  }

  /**
   * @description
   */
  @Transactional
  @Override
  public void upregister() {
    Long currentId = BaseContext.getCurrentId();
    Long employerId=employerMapper.getEmployerIdByUserId(currentId);
    if(employerMapper.selectEmployerCount(employerId)>0) {
      throw new BaseException("雇主当前还有任务未完成，不可以注销");
    }
    employerMapper.unregisterEmployer(currentId);
    userMapper.unregisterUser(currentId);
  }


  /**
   * 雇主评论工人
   *
   * @param taskId
   * @param workerRating
   */
  @Override
  public void commentWorker(Long taskId, int workerRating) {
    Task task = employerMapper.getById(taskId);
    if (task.getWorkerRating() != null) {
      throw new DeletionNotAllowedException("已评价，不可重复评价");
    }
    if (workerRating > 10 || workerRating < 0) {
      throw new DeletionNotAllowedException("评分输入错误，请输入0~10");
    }
    employerMapper.commentWorker(taskId, workerRating);
  }

  /**
   * 更改工人信誉
   *
   * @param taskId
   * @param workerRating
   */
  @Override
  public void updateWorkerCredit(Long taskId, int workerRating) {
    Worker worker = employerMapper.getWorkerById(taskId);
    if (worker.getWorkerId() == null) {
      throw new DeletionNotAllowedException("用户不存在，请重新输入");
    }
    Long workerId = worker.getWorkerId();
    int workerCredit = worker.getWorkerCredit() - 5 + workerRating;
    if (workerCredit > 100) {
      workerCredit = 100;
    }
    if (workerCredit < 0) {
      workerCredit = 0;
    }
    employerMapper.updateWorkerCredit(workerId, workerCredit);
  }

  /**
   * 雇主查看信誉记录
   *
   * @param userId
   * @return
   */
  @Override
  public List<String> checkCreditRecording(Long userId) {
    List<String> recordings = employerMapper.getEmployerCreditRecording(userId);
    return recordings;
  }

  /**
   * 雇主查看钱包余额记录
   *
   * @param userId
   * @return
   */
  @Override
  public List<String> checkCountRecording(Long userId) {
    List<String> recordings = employerMapper.getEmployerCountRecording(userId);
    return recordings;
  }


  /**
   * 创建信誉记录
   *
   * @param taskId
   * @param workerRating
   */
  @Override
  public void createCreditRecording(Long taskId, int workerRating) {
    Requirement requirement = employerMapper.getRequirementById(taskId);
    Worker worker = employerMapper.getWorkerById(taskId);
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String localDateTime = formatter.format(LocalDateTime.now());
    if (workerRating < 5) {
      int rating = 5 - workerRating;
      Recording recording = Recording.builder()
          .recordingContent(
                  localDateTime + " 完成" + " '" + requirement.getRequireTitle() + "' 订单,信誉度-"
                  + rating)
          .recordingType(1)
          .userId(worker.getUserId())
          .build();
      employerMapper.createCreditRecording(recording);
    } else {
      int rating = workerRating - 5;
      Recording recording = Recording.builder()
          .recordingContent(
                  localDateTime + " 完成" + " '" + requirement.getRequireTitle() + "' 订单,信誉度+"
                  + rating)
          .recordingType(1)
          .userId(worker.getUserId())
          .build();
      employerMapper.createCreditRecording(recording);
    }
  }


}
